#pragma once
#include "Data.h"
#include "Utility.h"


// event, enum,  RTTI class, member data, 
/*
event
*/
struct EventArgDef
{
	EventArgDef( const char* name,  EDataType dataType);

	const char*		Name;
	EDataType		DataType;
	EventArgDef*	Next;
};

struct ClassDef;
struct EventDef
{
	EventDef( const char* name);
	const char*		Name;
	EventArgDef*	ArgList;
	s32_t			ID;

	static TArray< EventDef*> sEventArray;
};

/*
functions
*/
struct FuncArgDef
{
	FuncArgDef( const char* name, EDataType type);

	const char* Name;
	EDataType	DataType;
	bool		HasDefaultVal;
	bool		IsOut;
	FuncArgDef*	Next;
};

typedef void (*ObjFunc_Bind)( Obj*, void* argList[]);
struct FuncBind
{
	FuncBind( const char* name, ObjFunc_Bind bindFunc);

	const char*		Name;
	FuncArgDef*		ArgList;
	ObjFunc_Bind	Bind_ObjFunc_Adp;
	s32_t			Index;
};

/*
enum
*/
struct EnumValue
{
	EnumValue( const char*, s32_t val);
	const char*		Name;
	s32_t			Value;
	EnumValue*	Next;
};

struct EnumDef
{
	EnumDef( const char* name);

	const char* Name;
	EnumValue*	ItemList;
};


struct StructDef;

/*
prop data
*/
struct PropDef
{
	PropDef( const char* name, EDataType type, s32_t pos);
	const char* Name;
	s32_t		Pos;

	s32_t		Index;

	ClassDef*	OwnerCls;
	StructDef*	OwnerStruct;

	EDataType	Type;

	union
	{
		ClassDef*	ClassType;
		StructDef*	StructType;
		EnumDef*	EnumType;
	};

	bool EditorReadOnly: 1;
	bool Editable: 1;
	bool IsArray: 1;

	bool IsOwnerLink:1;

	bool KismetVar: 1;
	bool IsSaveToDisk: 1;


};

struct PropData
{
	void CopyTo( PropData&);

	s32_t Num();
	void* operator[](s32_t index);
	void SetArrayNum( s32_t num);

	PropDef*	Def;
	void*		Data;
};

/*
StructDef
*/
typedef void (*StructArray_CopyFunc)( void* dstTArray, void* srcTArray);
typedef void (*StructArray_ResizeFunc)( void* dstTArray, s32_t);

struct StructDef
{
	StructDef( const char* name, s32_t cppSize);

	const char*			Name;
	PropDef*			GetProp( const char* );
	void				_defProp( PropDef* );

	TArray< PropDef*>	Props;
	s32_t				CppSize;

	StructArray_ResizeFunc ArrayResizeFunc;
	StructArray_CopyFunc ArrayCopyFunc;
	void CopyStruct( void* dstStrc, void* srcStrc);
	bool GetMemberData( void* stcPtr, PropDef* def, PropData& propData);
};

/*
RTTI
*/
typedef Obj* (*Obj_CreateFunc)();

struct ClassDef
{
	// for native cls using
	ClassDef( const char* name, ClassDef* super, Obj_CreateFunc createFunc);

	static ClassDef* GetClass( const char*);

	bool IsTypeOf( ClassDef* testType);

	const char* Name;
	ClassDef* const SuperCls;

	Obj_CreateFunc const CreateFunc;
	Obj* New();

	inline void InitBegin()
	{
		_check( SuperCls->PropIndexStart != -1);
		_check( SuperCls->BindFuncIndexStart != -1);

		PropIndexStart = SuperCls->PropIndexStart + SuperCls->Props.Num();
		BindFuncIndexStart = SuperCls->BindFuncIndexStart + SuperCls->BindFuncs.Num();
	}

	////////////////Prop////////////////
	PropDef* GetProp( const char* );
	void _defProp( PropDef* );

	inline TArray< PropDef*>::Iterator PropIt()
	{
		return TArray< PropDef*>::Iterator( Props);
	}

	TArray< PropDef*>	Props;
	s32_t				PropIndexStart;


	////////////////OperaDef////////////////
	void	_bindFunc( FuncBind* );

	TArray< FuncBind*>	BindFuncs;
	s32_t				BindFuncIndexStart;

	void GetInheritClassList( TArray<ClassDef*>& );

	static void Shutdown();
private:
	static TMap< const char*, ClassDef*> sClsMap;
};

